#pragma once

#include "Socket.hpp"
#include "Addr.hpp"
#include <memory>
#include<signal.h>
#include<unistd.h>
#include<functional>
#include<string>

using task_t = std::function<std::string(std::string& buffer)>;



class TcpServer
{
private:
    static void CustomIO(std::shared_ptr<Socket> _sockfd,Inet_Addr _Client,task_t task)
    {
        std::string _buffer;
        while(1)
        {
            _sockfd->Recv(&_buffer);
            std::string ret = task(_buffer);
            _sockfd->Send(ret);
        }

        _sockfd->Close();

    }



public:
    TcpServer(uint16_t port,task_t task)
        : _port(port), _listenSocket(std::make_unique<TcpSocket>()),_task(task)
    {
    }

    void Init()
    {
        _listenSocket->BulidSocket(_port);
    }

    void Start()
    {
        signal(SIGCHLD,SIG_IGN);
        while (1)
        {
            Inet_Addr _Client;
            std::shared_ptr<Socket> _sockfd = _listenSocket->Accept(&_Client);

            if(fork() == 0)
            {
                _listenSocket->Close();
                CustomIO(_sockfd,_Client,_task);
                exit(0);
            }
            _sockfd->Close();
        }
    }

    ~TcpServer()
    {
    }

private:
    std::unique_ptr<Socket> _listenSocket;
    uint16_t _port;
    task_t _task;
};
